////////////////////////////////////////////////////////////////////////////////
/// @file    i2s_config.c
/// @author  AE TEAM
/// @brief   THIS FILE PROVIDES ALL THE SYSTEM FUNCTIONS.
////////////////////////////////////////////////////////////////////////////////
/// @attention
///
/// THE EXISTING FIRMWARE IS ONLY FOR REFERENCE, WHICH IS DESIGNED TO PROVIDE
/// CUSTOMERS WITH CODING INFORMATION ABOUT THEIR PRODUCTS SO THEY CAN SAVE
/// TIME. THEREFORE, MINDMOTION SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT OR
/// CONSEQUENTIAL DAMAGES ABOUT ANY CLAIMS ARISING OUT OF THE CONTENT OF SUCH
/// HARDWARE AND/OR THE USE OF THE CODING INFORMATION CONTAINED HEREIN IN
/// CONNECTION WITH PRODUCTS MADE BY CUSTOMERS.
///
/// <H2><CENTER>&COPY; COPYRIGHT MINDMOTION </CENTER></H2>
////////////////////////////////////////////////////////////////////////////////

#if 0
/// change logs:
/// Date           Author          Notes
/// 2020-00-00
#endif
// Define to prevent recursive inclusion
#define _I2S_CONFIG_C_

// Files includes
#include "HAL_conf.h"
#include "HAL_device.h"
#include "i2s_config.h"
////////////////////////////////////////////////////////////////////////////////
/// @addtogroup MM32_Example_Layer
/// @{

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup MAIN
/// @{

////////////////////////////////////////////////////////////////////////////////
/// @addtogroup MAIN_Exported_Constants
/// @{




static void I2S3_GPIO_Config(void);

static void I2S_Mode_Config(SPI_I2S_STANDARD_TypeDef usStandard, SPI_I2S_DATAFORMAT_TypeDef usWordLen, SPI_I2S_AUDIO_FREQ_TypeDef usAudioFreq, SPI_I2S_TRANS_MODE_TypeDef usMode);

////////////////////////////////////////////////////////////////////////////////
/// @brief  config the codec I2S interface
/// @note   None
/// @param  None
/// @retval None
////////////////////////////////////////////////////////////////////////////////
void I2S_CODEC_Init(void)
{
    I2S3_GPIO_Config();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief  I2S start play tone with parameters
/// @note   addtional config the transmit mode as I2S_Mode_MasterTx
/// @param  usStandard  supported standard
///         usWordLen   bit length
///         usAudioFreq audio frequence
/// @retval None
////////////////////////////////////////////////////////////////////////////////
void I2S_StartPlay(SPI_I2S_STANDARD_TypeDef usStandard, SPI_I2S_DATAFORMAT_TypeDef usWordLen, SPI_I2S_AUDIO_FREQ_TypeDef usAudioFreq)
{
    // config I2S interface as standard, bit length, frequence ,the Master Tx mode
    I2S_Mode_Config(usStandard, usWordLen, usAudioFreq, I2S_Mode_MasterTx);
    SPI3->GCTL |= 0xF;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief  config the codec I2S interface
/// @note   None
/// @param  buf input buffer
///         num input buffer number
/// @retval None
////////////////////////////////////////////////////////////////////////////////
void I2S3_TX_DMA2_Init(u16* buf, u16 num)
{
    DMA_InitTypeDef  DMA_InitStructure;

    RCC_AHBPeriphClockCmd(RCC_AHBENR_DMA2, ENABLE);
    DMA_DeInit(DMA2_Channel2);

    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32) & (SPI3->TXREG);
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buf;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                          //Memory to Peripheral
    DMA_InitStructure.DMA_BufferSize = num;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_InitStructure.DMA_Auto_reload = DMA_Auto_Reload_Enable;
    DMA_Init(DMA2_Channel2, &DMA_InitStructure);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief  stop the codec I2S interface
/// @note   None
/// @param  None
/// @retval None
////////////////////////////////////////////////////////////////////////////////
void I2S_Stop(void)
{
    SPI_ITConfig(SPI3, SPI_IT_TX, DISABLE);
    SPI_ITConfig(SPI3, SPI_IT_RX, DISABLE);

    I2S_Cmd(SPI3, DISABLE);

    RCC_APB1PeriphClockCmd(RCC_APB1ENR_SPI3, DISABLE);
}


////////////////////////////////////////////////////////////////////////////////
/// @brief  config the codec I2S GPIO config
/// @note   None
/// @param  None
/// @retval None
////////////////////////////////////////////////////////////////////////////////
static void I2S3_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    // I2S  MCLK, SD, CK and WS pins configuration
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_SPI3, ENABLE);

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_6);                       //I2S WS
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_6);                        //I2S CK  I2S_SCK
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_6);                        //I2S SD  I2S_DATAOUT  MOSI
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_5);                        //I2S MCK I2S_MCLK

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    // config as the control I/O for power on or enter standby
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

}

////////////////////////////////////////////////////////////////////////////////
/// @brief  I2S mode config with parameters
/// @note   None
/// @param  usStandard  supported standard
///         usWordLen   bit length
///         usAudioFreq audio frequence
///         usMode      config the transmit mode as I2S_Mode_MasterTx or I2S_Mode_MasterRx
/// @retval None
////////////////////////////////////////////////////////////////////////////////
static void I2S_Mode_Config(SPI_I2S_STANDARD_TypeDef usStandard, SPI_I2S_DATAFORMAT_TypeDef usWordLen, SPI_I2S_AUDIO_FREQ_TypeDef usAudioFreq, SPI_I2S_TRANS_MODE_TypeDef usMode)
{
    I2S_InitTypeDef I2S_InitStructure;

    if ((usMode == I2S_Mode_SlaveTx) && (usMode == I2S_Mode_SlaveRx)) {
        return;
    }
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_SPI3, ENABLE);
    SPI_DeInit(SPI3);
    RCC_APB1PeriphClockCmd(RCC_APB1ENR_SPI3, ENABLE);
    if (usMode == I2S_Mode_MasterTx) {
        I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
        I2S_InitStructure.I2S_Standard = usStandard;
        I2S_InitStructure.I2S_DataFormat = usWordLen;
        I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
        I2S_InitStructure.I2S_AudioFreq = usAudioFreq;
        I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
        I2S_Init(SPI3, &I2S_InitStructure);
    }
    else if (usMode == I2S_Mode_MasterRx) {
        I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;
        I2S_InitStructure.I2S_Standard = usStandard;
        I2S_InitStructure.I2S_DataFormat = usWordLen;
        I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
        I2S_InitStructure.I2S_AudioFreq = usAudioFreq;
        I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
        I2S_Init(SPI3, &I2S_InitStructure);
    }

    SPI_DMACmd(SPI3, ENABLE);
    I2S_Cmd(SPI3, ENABLE);
}



/// @}

/// @}

/// @}

